package com.syh.jn.scm.infrastructure.repository.impl.supplier.finance;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AggregateRepoHibernateImplTmpl;
import com.syh.jn.scm.domain.supplier.entity.finance.OrderExpensesBill;
import com.syh.jn.scm.domain.supplier.entity.finance.OrderExpensesBillItem;
import com.syh.jn.scm.domain.supplier.repository.finance.OrderExpensesBillRepository;
import com.syh.jn.scm.infrastructure.repository.model.finance.OrderExpensesBillItemModel;
import com.syh.jn.scm.infrastructure.repository.model.finance.OrderExpensesBillModel;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public class OrderExpensesBillRepositoryImpl implements OrderExpensesBillRepository {
  private HibernateTemplate hibernateTemplate;
  private AggregateRepoHibernateImplTmpl<OrderExpensesBill, OrderExpensesBillModel, Long> orderExpensesBillRepoHibernateImplTmpl;
  private AggregateRepoHibernateImplTmpl<OrderExpensesBillItem, OrderExpensesBillItemModel, Long> orderExpensesBillItemRepoHibernateImplTmpl;

  @Autowired
  public OrderExpensesBillRepositoryImpl(HibernateTemplate hibernateTemplate) {
    this.hibernateTemplate = hibernateTemplate;
    this.orderExpensesBillRepoHibernateImplTmpl =
            new AggregateRepoHibernateImplTmpl.Builder().hibernateTemplate(hibernateTemplate).entityClass(OrderExpensesBill.class).modelClass(OrderExpensesBillModel.class).idClass(Long.class).build();
    this.orderExpensesBillItemRepoHibernateImplTmpl =
            new AggregateRepoHibernateImplTmpl.Builder().hibernateTemplate(hibernateTemplate).entityClass(OrderExpensesBillItem.class).modelClass(OrderExpensesBillItemModel.class).idClass(Long.class).build();
  }

  /**
   * 添加订单费用表
   * @param orderExpensesBill
   * @return
   */
  @Override
  public Long add(OrderExpensesBill orderExpensesBill) {
    OrderExpensesBillModel orderExpensesBillModel = this.orderExpensesBillRepoHibernateImplTmpl.add(orderExpensesBill);
    Long id = orderExpensesBillModel.getId();
    this.saveBillItems(id,orderExpensesBill.getItems());
    return id;
  }


  /**
   * 修改订单费用表
   * @param orderExpensesBill
   */
  @Override
  public void update(OrderExpensesBill orderExpensesBill) {
    this.orderExpensesBillRepoHibernateImplTmpl.update(orderExpensesBill);
    this.deleteBillItems(orderExpensesBill.getId());
    this.saveBillItems(orderExpensesBill.getId(),orderExpensesBill.getItems());
  }

  /**
   * 重载update方法 选择是否更新item
   * @param orderExpensesBill 更新的订单费用表
   * @param isUpdateItem true：更新item  false：不更新item
   */
  @Override
  public void update(OrderExpensesBill orderExpensesBill, boolean isUpdateItem) {
    if (isUpdateItem) {
      this.update(orderExpensesBill);
    } else {
      this.orderExpensesBillRepoHibernateImplTmpl.update(orderExpensesBill);
    }
  }

  /**
   * 保存订单费用明细
   * @param orderId 订单费用表id
   * @param items 费用明细
   */
  private void saveBillItems(Long orderId, List<OrderExpensesBillItem> items) {
    items.forEach(item-> {
      item.setExpensesBillId(orderId);
      this.orderExpensesBillItemRepoHibernateImplTmpl.add(item);
    });
  }

  /**
   * 删除订单明细
   * @param orderId 订单费用表id
   */
  private void deleteBillItems(Long orderId) {
    String hql = "DELETE FROM OrderExpensesBillItemModel item WHERE item.expensesBillId = :orderId";
    Query query = this.hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql);
    query.setParameter("orderId",orderId);
    query.executeUpdate();
  }

  /**
   * 根据订单费用表id获取费用明细
   * @param id
   * @return
   */
  @Override
  public List<OrderExpensesBillItem> getBillItemsByBillId(Long id) {
    String hql = "FROM OrderExpensesBillItemModel item WHERE item.expensesBillId = ?";
    List<OrderExpensesBillItemModel> orderExpensesBillItemModels = (List<OrderExpensesBillItemModel>) this.hibernateTemplate.find(hql,id);
    List<OrderExpensesBillItem> orderExpensesBillItems = new ArrayList<>();
    orderExpensesBillItemModels.forEach(orderExpensesBillItemModel -> {
      OrderExpensesBillItem  item = new OrderExpensesBillItem();
      ExtBeanUtils.copyProperties(orderExpensesBillItemModel,item);
      orderExpensesBillItems.add(item);
    });
    return orderExpensesBillItems;
  }

  /**
   * 删除订单费用表
   * @param aLong 订单费用表id
   */
  @Override
  public void removeById(Long aLong) {
    this.deleteBillItems(aLong);
    this.orderExpensesBillRepoHibernateImplTmpl.removeById(aLong);
  }

  /**
   * 删除订单费用表
   * @param orderExpensesBill
   */
  @Override
  public void remove(OrderExpensesBill orderExpensesBill) {
    this.removeById(orderExpensesBill.getId());
  }

  @Override
  public OrderExpensesBill getById(Long aLong) {
    OrderExpensesBill orderExpensesBill = this.orderExpensesBillRepoHibernateImplTmpl.getById(aLong);
    orderExpensesBill.setItems(this.getBillItemsByBillId(aLong));
    return orderExpensesBill;
  }

  @Override
  public OrderExpensesBill getOne(Wrapper wrapper) {
    OrderExpensesBill orderExpensesBill = this.orderExpensesBillRepoHibernateImplTmpl.getOne(wrapper);
    orderExpensesBill.setItems(this.getBillItemsByBillId(orderExpensesBill.getId()));
    return orderExpensesBill;
  }

  @Override
  public boolean contains(Long aLong) {
    return this.getById(aLong) == null ? false : true;
  }

  @Override
  public List<OrderExpensesBill> getList(Wrapper wrapper) {
    List<OrderExpensesBill> orderExpensesBills = this.orderExpensesBillRepoHibernateImplTmpl.getList(wrapper);
    return orderExpensesBills;
  }

  @Override
  public List<OrderExpensesBill> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    List<OrderExpensesBill> orderExpensesBills = this.orderExpensesBillRepoHibernateImplTmpl.findListPage(wrapper,startRow,count);
    return orderExpensesBills;
  }

  @Override
  public int getCount(Wrapper wrapper) {
    return this.orderExpensesBillRepoHibernateImplTmpl.getCount(wrapper);
  }
}
